package com.eternal.main.model;

import android.view.View;

import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.databinding.BindingAdapter;
import androidx.databinding.ObservableBoolean;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;
import androidx.core.content.ContextCompat;

import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.concat.DeviceInfo;
import com.eternal.base.concat.DeviceTFP;
import com.eternal.base.concat.PortInfo;
import com.eternal.base.global.BluetoothKey;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.binding.command.BindingCommand;
import com.eternal.framework.binding.command.BindingConsumer;
import com.eternal.framework.bus.Messenger;
import com.eternal.framework.component.AppManager;
import com.eternal.framework.utils.Utils;
import com.eternal.main.MainActivity;
import com.eternal.main.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by Administrator
 * On 2020/4/24
 * Description:
 *
 * @author Administrator
 */
public class ItemModel {
    private static final String FAH = "℉";
    private static final String DEGREE = "℃";

    private String mac;
    private boolean isConnected;
    private byte type;

    public ObservableField<String> name = new ObservableField<>();
    public ObservableField<String> time = new ObservableField<>();
    public ObservableField<String> device = new ObservableField<>();
    public ObservableInt tmpState = new ObservableInt();                                            //温度状态
    public ObservableInt perState = new ObservableInt();                                            //湿度状态
    public ObservableInt fanState = new ObservableInt();                                            //风扇状态
    public ObservableInt fanType = new ObservableInt();

    public ObservableField<String> tmpSize = new ObservableField<>();                               //温度
    public ObservableField<String> perSize = new ObservableField<>();                               //湿度
    public ObservableField<String> fanSize = new ObservableField<>();
    public ObservableField<String> tmpFlag = new ObservableField<>();
    public ObservableBoolean fanVisibility = new ObservableBoolean();
    public ObservableBoolean masterVisibility = new ObservableBoolean();
    public ObservableInt timeColor = new ObservableInt();

    public ObservableBoolean open = new ObservableBoolean();
    public ObservableBoolean isConnet = new ObservableBoolean();

    // xml使用的是静态布局，不好动态添加，这里先写死，后续合并重复代码
    public PortModel portModel0 = new PortModel();
    public PortModel portModel1 = new PortModel();
    public PortModel portModel2 = new PortModel();
    public PortModel portModel3 = new PortModel();
    public PortModel portModel4 = new PortModel();
    public PortModel portModel5 = new PortModel();
    public PortModel portModel6 = new PortModel();
    public PortModel portModel7 = new PortModel();
    public PortModel portModel8 = new PortModel();
    public PortModel portModel9 = new PortModel();
    private List<PortModel> portModelList = new ArrayList<>();

    private DeviceInfo deviceInfo;

    private boolean isUpdateComplete;

    ItemModel(final DeviceInfo device) {
        deviceInfo = device;
        mac = device.mac;
        name.set(device.name);
        type = device.type;
        this.device.set(Utils.getString(R.string.tip_name_name,
                ProtocolTransformer.getType(device.type),
                device.typeName));
        isConnet.set(false);
        time.set(Utils.getString(R.string.tip_last, ProtocolTransformer.getTime(device.connectTime)));
        timeColor.set(ContextCompat.getColor(Utils.getContext(), R.color.color_FF2D55));
        portModelList.add(portModel0);
        portModelList.add(portModel1);
        portModelList.add(portModel2);
        portModelList.add(portModel3);
        portModelList.add(portModel4);
        portModelList.add(portModel5);
        portModelList.add(portModel6);
        portModelList.add(portModel7);
        portModelList.add(portModel8);
        portModelList.add(portModel9);
        for (final PortModel portModel : portModelList) {
            portModel.setListener(new PortModel.OnClickListener() {
                @Override
                public void onClick(byte port) {
                    if (deviceInfo.portList != null) {
                        for (PortInfo portInfo : deviceInfo.portList) {
                            if (portInfo.id == port && portInfo.isPlug) {
                                pushToDetail(port);
                                Messenger.getDefault().send(ItemModel.this, MainModel.CHOOSE_PORT);
                            }
                        }
                    }
                }
            });
        }
        update();
    }

    public DeviceInfo getDeviceInfo() {
        return deviceInfo;
    }

    void updateTFP(DeviceTFP tfp) {
        deviceInfo.update(tfp);
        update();
        isUpdateComplete = true;
    }

    void update() {
        if (deviceInfo.isDegree) {
            if (!DEGREE.equals(tmpFlag.get())) {
                tmpFlag.set(DEGREE);
            }
        } else {
            if (!FAH.equals(tmpFlag.get())) {
                tmpFlag.set(FAH);
            }
        }
        // 是否显示
        if (type == BluetoothKey.DEVICE_TYPE_A) {
            tmpSize.set(ProtocolTransformer.getString4Degree(deviceInfo.tmp, deviceInfo.isDegree));
            fanVisibility.set(true);
            masterVisibility.set(false);
            open.set(true);
        } else if (type == BluetoothKey.DEVICE_TYPE_B) {
            tmpSize.set(ProtocolTransformer.getString4Degree(deviceInfo.tmp, deviceInfo.isDegree));
            fanVisibility.set(false);
            masterVisibility.set(false);
            open.set(true);
        } else if (type == BluetoothKey.DEVICE_TYPE_E) {
            tmpSize.set(ProtocolTransformer.getString4Degree(deviceInfo.tmp, deviceInfo.isDegree));
            fanVisibility.set(true);
            masterVisibility.set(true);
            open.set(deviceInfo.choosePort == 0);
        } else { // C
            tmpSize.set(ProtocolTransformer.getTmpString(deviceInfo.tmp, deviceInfo.isDegree));
            fanVisibility.set(false);
            masterVisibility.set(false);
            open.set(true);
        }

        fanType.set(type == BluetoothKey.DEVICE_TYPE_E ? R.mipmap.icon_fan : R.mipmap.fan_select);

        perSize.set(ProtocolTransformer.getPer(deviceInfo.hum));
        tmpState.set(getState(deviceInfo.tmpState));
        perState.set(getState(deviceInfo.humState));
        // 设置负载
        if (fanVisibility.get()) {
            fanSize.set(String.valueOf(deviceInfo.fan));
            fanState.set(getState(deviceInfo.fanState));
        } else {
            fanSize.set(deviceInfo.fan == 0 ? "OFF" : "ON");
        }
        if (deviceInfo.portList != null) {
            Collections.sort(deviceInfo.portList, new Comparator<PortInfo>() {
                @Override
                public int compare(PortInfo info, PortInfo info2) {
                    if (info.isPlug && !info2.isPlug) {
                        return -1;
                    } else if (info.isPlug) {
                        return 0;
                    } else {
                        return 1;
                    }
                }
            });
            for (int i = 0; i < deviceInfo.portList.size(); i++) {
                portModelList.get(i).update(deviceInfo.portList.get(i));
            }
        }
    }

    void update(List<PortInfo> portList) {
        if (deviceInfo == null || deviceInfo.portList == null || portList == null || deviceInfo.portList.size() != portList.size()) {
            deviceInfo.portList = portList;
        } else {
            for (PortInfo port1 : deviceInfo.portList) {
                for (PortInfo port2 : portList) {
                    if (port1.id == port2.id) {
                        port1.name = port2.name;
                    }
                }
            }
        }
        update();
    }

    void update(String name) {
        this.name.set(name);
    }

    void disconnect() {
        timeColor.set(ContextCompat.getColor(Utils.getContext(), R.color.color_FF2D55));
        time.set(Utils.getString(R.string.tip_last,
                ProtocolTransformer.getTime(System.currentTimeMillis())));
        isConnected = false;
        isConnet.set(isConnected);
    }

    void connect(long time) {
        timeColor.set(ContextCompat.getColor(Utils.getContext(), android.R.color.white));
        this.time.set(Utils.getString(R.string.tip_connect,
                ProtocolTransformer.getTime(time)));
        isConnected = true;
        isConnet.set(isConnected);
    }

    boolean needRefresh() {
        return type == BluetoothKey.DEVICE_TYPE_A || type == BluetoothKey.DEVICE_TYPE_B || type == BluetoothKey.DEVICE_TYPE_E;
    }

    public String getMac() {
        return mac;
    }

    private int getState(byte state) {
        switch (state) {
            case 0:
                return R.mipmap.stead_trend;
            case 1:
                return R.mipmap.decrease_trend;
            default:
                return R.mipmap.increase_trend;
        }
    }

    public BindingCommand<Void> onDetail = new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {
            if (open.get()) {
                pushToDetail((byte) 0x0);
            }
        }
    });

    public BindingCommand<Boolean> onChecked = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean aBoolean) {
            if (isUpdateComplete) {
                deviceInfo.choosePort = aBoolean ? 0x0 : (deviceInfo.portList == null || deviceInfo.portList.size() == 0) ? 0 : deviceInfo.portList.get(0).id;
                Messenger.getDefault().send(ItemModel.this, MainModel.CHOOSE_PORT);
            }
        }
    });

    void pushToDetail(byte port) {
        deviceInfo.choosePort = port;
        Postcard post = ARouter.getInstance().build(RouterActivityPath.Detail.PAGE_DETAIL)
                .withString(ActivityEvent.DEVICE_MAC, mac)
                .withByte(ActivityEvent.DEVICE_TYPE, type)
                .withByte(ActivityEvent.DEVICE_PORT, port)
                .withTransition(R.anim.right_in, R.anim.left_out);
        if (!isConnected) {
            post.withString(ActivityEvent.DEVICE_TIME, time.get());
        }
        post.navigation(AppManager.getAppManager().currentActivity());
        Messenger.getDefault().send(ItemModel.this, MainActivity.ON_ITEM_CLICK);
    }

    public BindingCommand<Void> onDelete = new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {

            Messenger.getDefault().send(ItemModel.this, MainActivity.SHOW_DELETE_DIALOG);
        }
    });

    @BindingAdapter(value = {"layout_conditionalConstraint_startSide",
            "layout_conditionalConstraint_toEndId",
            "layout_conditionalConstraint_endSide",
            "layout_conditionalConstraint_condition"}, requireAll = true)
    public static void setLayoutConstraintStartToEndOf(View view, int startSide, int endId, int endSide, Boolean condition) {
        if (!(view.getParent() instanceof ConstraintLayout)) {
            ConstraintSet constraintSet = new ConstraintSet();
            ConstraintLayout constraintLayout = (ConstraintLayout) view.getParent();
            constraintSet.clone(constraintLayout);
            if (condition) {
                constraintSet.connect(view.getId(), startSide, endId, endSide);
            } else {
                constraintSet.clear(view.getId(), startSide);
            }
            constraintSet.applyTo(constraintLayout);
        }
    }

}
